package xyz.xtt.asset.vo;

import static xyz.xtt.common.asset.AssertUtils.isNull;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;

import com.google.common.collect.Lists;
import com.google.common.primitives.Longs;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.asset.api.enums.AssetTypeEnum;
import xyz.xtt.asset.api.enums.BizTypeEnum;
import xyz.xtt.asset.api.enums.OwnerTypeEnum;
import xyz.xtt.asset.api.enums.SellPatternEnum;
import xyz.xtt.asset.api.enums.ShowStateEnum;
import xyz.xtt.asset.client.request.MintDataVo;
import xyz.xtt.asset.client.request.MintRequest;
import xyz.xtt.asset.constants.ErrorMessage;
import xyz.xtt.asset.entity.TblAsset;
import xyz.xtt.asset.entity.TblAssetExt;
import xyz.xtt.asset.entity.TblAssetStaticResource;
import xyz.xtt.asset.enums.FileTypeEnum;

/**
 * 资产对象转换
 * 
 * @author huqibo
 * @date 2025/01/14
 */
@Slf4j
public class AssetConvert {
	private static TblAsset buildAsset(MintRequest request) {
		String authorId = request.getAuthorId();
		BigDecimal price = request.getPrice();
		long id = IdUtil.getSnowflakeNextId();
		AssetTypeEnum assetType = AssetTypeEnum.convert(request.getAssetType());
		isNull(assetType, ErrorMessage.ASSET_TYPE_ERR, () -> log.info("buildAsset:{} assetType ex", JSONUtil.toJsonStr(request)));
		OwnerTypeEnum ownerType = OwnerTypeEnum.queryConvert(request.getOwnerType());
		isNull(ownerType, ErrorMessage.OWNER_TYPE_ERR, () -> log.info("buildAsset:{} ownerType ex", JSONUtil.toJsonStr(request)));
		BizTypeEnum bizType = BizTypeEnum.queryConvert(request.getBizType());
		isNull(bizType, ErrorMessage.BIZ_TYPE_ERR, () -> log.info("buildAsset:{} bizType ex", JSONUtil.toJsonStr(request)));
		Long parentId = Objects.equals(request.getParentId(), 0L) ? Longs.tryParse(request.getBizId()) : request.getParentId();
		Integer secondType = Objects.equals(request.getRootAssetId(), 0L) ? 0 : request.getSecondType();

		// 创建时想控制拥有方时使用此字段
		String ownerId = StringUtils.isBlank(request.getOwnerId()) ? authorId : request.getOwnerId();
		long pid = Objects.isNull(parentId) ? IdUtil.getSnowflakeNextId() : parentId;
		Long rootAssetId = Objects.equals(request.getRootAssetId(), 0L) ? id : request.getRootAssetId();
		return TblAsset
				.builder()
				.id(id)
				.rootAssetId(rootAssetId) 		// 铸造时 资产ID根ID相同
				.assetNo(IdUtil.getSnowflakeNextId())
				.assetName(request.getName())
				.description(request.getDescription())
				.price(price)
				.guidePrice(price)
				.unit(request.getUnit())
				.amount(request.getAmount())
				.authorId(authorId)
				.ownerId(ownerId)
				.cooperationId(ownerId)
				.firstType(assetType.code())
				.secondType(secondType)
				.showState(ShowStateEnum.NORMAL.code())
				.sellPattern(SellPatternEnum.NORMAL.code())
				.createDatetime(System.currentTimeMillis())
				.lastModifyDatetime(System.currentTimeMillis())
				.goodsId(request.getBizId())
				.parentId(String.valueOf(pid))
				.ownerType(ownerType.code())
				.bizType(bizType.dbType())
				.sellable(request.getSellable())
				.giftable(request.getGiftable())
				.rankable(request.getRankable())
				.collectionId(request.getCollectionId())
				.build();
	}

	private static TblAssetExt buildAssetExt(MintRequest request, Long assetId) {
		Integer chainUp = Optional.ofNullable(request.getUpChain()).map(x -> Objects.equals(Boolean.TRUE, x)).orElse(Boolean.TRUE) ? 1 : 0;
		MetaDataParams params = new MetaDataParams();
		String externalUrl = request.getExternalUrl();
		if (StringUtils.isNotBlank(externalUrl)) {
			params.setExternal_url(externalUrl);
		}
		params.setDescription(request.getDescription());
		params.setName(request.getName());
		params.setImage(request.getImage());
		List<MetaDataAttribute> list = Lists.newArrayList();
		List<MintDataVo> attributes = request.getAttributes();
		if (CollectionUtil.isNotEmpty(attributes)) {
			attributes.forEach(x -> {
				list.add(new MetaDataAttribute(x.getTraitType(), x.getValue()));
			});
		}
		params.setAttributes(list);
		return TblAssetExt
				.builder()
				.id(IdUtil.getSnowflakeNextId())
				.assetId(assetId)
				.tokenId(assetId)
				.referProtocol(request.getReferProtocol())
				.sellStartDatetime(request.getSellStartDatetime())
				.sellEndDatetime(request.getSellEndDatetime())
				.lastModifyDatetime(System.currentTimeMillis())
				.metadata(JSONUtil.toJsonStr(params))
				.upChain(chainUp)
				.seqNo(request.getSeqNo())
				.build();
	}

	private static TblAssetStaticResource buildStatic(MintRequest request, Long assetId) {
		String image = request.getImage();
		String externalUrl = request.getExternalUrl();
		String displayUri = StringUtils.isBlank(request.getDisplayUri()) ? request.getImage() : request.getDisplayUri();
		return TblAssetStaticResource
				.builder()
				.id(IdUtil.getSnowflakeNextId())
				.assetId(assetId)
				.logoUri(image)
				.displayUri(displayUri)
				.fileUri(externalUrl)
				.fileType(FileTypeEnum.IMG.code())
				.lastModifyTime(System.currentTimeMillis())
				.build();
	}

	public static AssetSynMessageSaveItem buildItem(MintRequest request) {
		TblAsset buildAsset = buildAsset(request);
		Long id = buildAsset.getId();
		return AssetSynMessageSaveItem.builder().asset(buildAsset).assetExt(buildAssetExt(request, id)).assetStaticResource(buildStatic(request, id)).build();
	}
}
